﻿using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CommandLib
{
    /// <summary>
    /// MongoDB操作
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class MongoHelper<T> : IDisposable
    {
        private string connStr = "";//服务器网址

        private string dbName = "";//数据库名称

        private IMongoClient client;//连接客户端

        private IMongoDatabase db;//连接数据库

        private string collName;//集合名称
        /// <summary>
        /// 返回数据库容器
        /// </summary>
        public IMongoCollection<T> Result { get; private set; }
        public MongoHelper()
        {

        }
        /// <summary>
        /// 构建服务
        /// </summary>
        /// <param name="connStr">服务器网址</param>
        /// <param name="dbName">数据库名称</param>
        /// <param name="collName">集合名称</param>
        public MongoHelper(string connStr, string dbName, string collName)
        {
            this.connStr = connStr;
            this.dbName = dbName;
            this.collName = collName;
            this.Init();
        }

        /// <summary>
        /// 初始化连接客户端
        /// </summary>
        private void Init()
        {
            if (client == null)
            {
                client = new MongoClient(this.connStr);
            }
            if (db == null)
            {
                db = client.GetDatabase(this.dbName);

                Result = db.GetCollection<T>(collName);
            }
        }

        /// <summary>
        /// 插入对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        public void Insert(T obj)
        {
            IMongoCollection<T> collention = db.GetCollection<T>(collName);
            collention.InsertOne(obj);
        }

        /// <summary>
        /// 字典形式插入
        /// </summary>
        /// <param name="dicInfo"></param>
        public void Insert(Dictionary<string, string> dicInfo)
        {
            var collection = db.GetCollection<BsonDocument>(collName);
            var document = new BsonDocument(dicInfo);
            collection.InsertOne(document);
        }

        /// <summary>
        /// 无条件查询，即返回全部
        /// </summary>
        /// <returns></returns>
        public List<T> Query()
        {
            var collection = db.GetCollection<BsonDocument>(collName);
            var rest = collection.Find(Builders<BsonDocument>.Filter.Empty);
            return rest.As<T>().ToList();
        }

        /// <summary>
        /// 按名称进行查询
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public List<T> Query(string key, object value)
        {
            var collection = db.GetCollection<T>(collName);
            var rest = collection.Find(Builders<T>.Filter.Eq(key, value));
            return rest.As<T>().ToList();
        }
        /// <summary>
        /// 按名称进行查询
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public List<T> Query(FilterDefinition<T> filter)
        {
            var collection = db.GetCollection<T>(collName);
            var rest = collection.Find(filter);
            return rest.As<T>().ToList();
        }


        /// <summary>
        /// 只查询一条
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public T QueryOne(string Id)
        {
            var collection = db.GetCollection<T>(collName);

            var rest = collection.Find(Builders<T>.Filter.Eq("Id", new ObjectId(Id))).Limit(1);
            return rest.As<T>().FirstOrDefault();
        }


        public UpdateResult UpdateOne(FilterDefinition<T> filter, UpdateDefinition<T> update, UpdateOptions options = null)
        {
            var collection = db.GetCollection<T>(collName);

            return collection.UpdateOne(filter, update, options);
        }

        /// <summary>
        /// 修改数据
        /// </summary>
        /// <param name="source"></param>
        /// <param name="Updata"></param>
        /// <returns></returns>
        public UpdateResult UpdateOne(KeyValuePair<string, object> source, KeyValuePair<string, object> Updata)
        {
            var collection = db.GetCollection<T>(collName);
            var model = Builders<T>.Filter.Eq(source.Key, source.Value);
            var updateoptin = Builders<T>.Update.Set(Updata.Key, Updata.Value);
            return collection.UpdateOne(model, updateoptin);
        }
        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public DeleteResult DeleteOne(KeyValuePair<string, object> source)
        {
            var collection = db.GetCollection<T>(collName);
            var model = Builders<T>.Filter.Eq(source.Key, source.Value);
            return collection.DeleteOne(model);
        }
        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public DeleteResult DeleteOne(FilterDefinition<T> filter)
        {
            var collection = db.GetCollection<T>(collName);
            return collection.DeleteOne(filter);
        }

        /// <summary>
        /// 删除集合
        /// </summary>
        /// <param name="collName"></param>
        public void DropCollection(string collName)
        {
            db.DropCollection(collName);
        }
        public void Dispose()
        {

            client?.Cluster.Dispose();
        }
    }
}
